package ihm.views.main.catalog;

import ihm.models.ATKmodel;
import ihm.views.equip.EquipBox;
import ihm.views.options.ATKjOptionPane;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.JTable;

import equipments.Items;
import equipments.enumeration.EquipmentSlots;

import systems.database.DataBaseHandler;
import systems.exceptions.database.NotConnectedException;
import systems.exceptions.database.StatementIsNullException;
import systems.exceptions.equipments.CanNotEquipThisItem;
import systems.languages.MultiLanguages;
import systems.rpgBuilder.Item;

public class CatalogTable extends JTable implements MouseListener{

  private static final long serialVersionUID = 1L;

  private static CatalogModel catalogModel;
  private ATKmodel model;

  private static String[] columnsMultilangueName = {
    "catalog.Name.label",
    "catalog.Level.label",
    "catalog.Quality.label",
    "catalog.Type.label",
    "catalog.ID.label"
  };

  private static String[] columnsName = new String[columnsMultilangueName.length];  
  private static ArrayList<CatalogEntry> rowsData = new ArrayList<CatalogEntry>();

  public CatalogTable(ATKmodel model)
  {
    super();
    this.updateColumnsName();
    catalogModel = new CatalogModel(columnsName);
    super.setModel(catalogModel);
    this.setAutoCreateRowSorter(true);
    this.addMouseListener(this);
    this.model = model;
  }


  private void updateColumnsName()
  {
    int index = 0;
    for(String columnMultiLangeName : CatalogTable.columnsMultilangueName)
      CatalogTable.columnsName[index++] = MultiLanguages.getProperties(columnMultiLangeName);
  }

  public void buildRows(ResultSet result)
  {
    rowsData = new ArrayList<CatalogEntry>();

    String[][] rawData;
    /*First we must to save the result into another variable in order to be 
    sure that it will not be modify.*/
    ResultSet tmp = result;

    int rowsCount = 0;
    int index=0;
    if(result == null)
    {
      rowsData = new ArrayList<CatalogEntry>();
      return;
    }
    //Count the ResultSet rows Number
    try {
      while(tmp.next())
        rowsCount ++ ;
      //System.out.println("Count : "+rowsCount);
      //Create the rowsData Array
      rawData = new String[rowsCount][5];
      //Then we put the cursor at the beginning
      result.first();
      while(result.next())
      {
        rawData[index][0] = "";
        rawData[index][1] = tmp.getString("level");
        rawData[index][2] = tmp.getString("quality");
        rawData[index][3] = "";
        rawData[index][4] = tmp.getString("id");
        index++;
      }
      for(int i=0; i<index; i++)
      {
        String name = getName(rawData[i][4]);
        if(!name.equalsIgnoreCase("null"))
        {
          rawData[i][0] = name;
          rowsData.add(new CatalogEntry(rawData[i]));
        }
      }

    } catch (SQLException e) {
      e.printStackTrace();
    }
    CatalogTable.catalogModel.updateData(rowsData);
  }

  private String getName(String itemId)
  {
    String name = "null";
    try {
      ResultSet res = DataBaseHandler.query("SELECT `body` FROM "+MultiLanguages.getProperties("database.Language.name")+" WHERE `oid` = "+itemId);
      res.first();
      name = res.getString("body");
      res.close();
      return name;
    } catch (NotConnectedException e) {
      e.printStackTrace();
    } catch (StatementIsNullException e) {
      e.printStackTrace();
    } catch (SQLException e) {
      //e.printStackTrace();
    }
    return name;
  }

  public void updateColumnsNameModel()
  {
    updateColumnsName();
    CatalogTable.catalogModel.updateColumns(CatalogTable.columnsName);
  }


  @Override
  public void mouseClicked(MouseEvent e)
  {
    Items itemInstance;
    Items oldItem;
    Item itemSelected;
    EquipmentSlots slot = null;
    LinkedList<equipments.enumeration.EquipmentSlots> slotsList;
    if (e.getClickCount() == 2) {
      JTable target = (JTable)e.getSource();
      int row = target.getSelectedRow();
      row = convertRowIndexToModel(row);
      CatalogEntry entrySelected= rowsData.get(row);
      itemSelected = model.getSelectedItem();
      slotsList = itemSelected.getSlotsList();
      //System.out.println("Ligne selectionn� "+entrySelected.getName());
      itemInstance = instanciateItem(itemSelected.getClassName(), entrySelected);
      if(slotsList.size() > 1 && !slotsList.isEmpty())
        slot = EquipBox.displaySlotsSelector(slotsList);
      else
        if(slotsList.size() == 1)
          slot = slotsList.getFirst();

      if(slot != null )
      {
        boolean replace = true;
        oldItem = model.getEquipment().getItem(slot);
        if(oldItem != null)
          replace = EquipBox.displayReplaceItem(slot, itemInstance, oldItem);
        if(replace)
        {
          try{
            model.setEquipments(slot, itemInstance);
          }catch(CanNotEquipThisItem e1){
            ATKjOptionPane.showMessageDialog(this, e1.toString(), "Error", ATKjOptionPane.ERROR_MESSAGE);
          }
        }
      }else{
        //TODO: Debug
        //System.out.println("Pas de slot");
      }
    }  
  }

  private Items instanciateItem(String className, CatalogEntry entrySelected)
  {
    Items itemInstance = null;
    try {
      itemInstance = (Items)Class.forName(className).newInstance();
      //System.out.println("Id "+entrySelected.getId());
      itemInstance.init(entrySelected.getId());
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
    return itemInstance;
  }

  @Override
  public void mouseEntered(MouseEvent e) {    
  }

  @Override
  public void mouseExited(MouseEvent e) {
  }

  @Override
  public void mousePressed(MouseEvent e) {    
  }

  @Override
  public void mouseReleased(MouseEvent e) {
  }
}
